package com.googlecode.cswish.test;

import java.util.List;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import com.googlecode.cswish.struts.ContextHolder;
import com.googlecode.cswish.struts.hibernate.HibernateConfiguration;
import com.googlecode.cswish.struts.hibernate.ISite;
import com.googlecode.cswish.struts.spring.ObjectFactory;
import com.googlecode.cswish.struts.spring.SystemEnv;

public class BaseSpringTestCase {

	@Resource
	protected ObjectFactory objectFactory;

	@Resource
	protected HibernateConfiguration configuration;
	
	public void autowire(Object bean) {
		objectFactory.autoWireBean(bean);
	}

	@Before
	public void setUp() {
		if (objectFactory != null) {
			autowire(this);
		} else {
			objectFactory = ObjectFactory.getInstance();
			autowire(this);
		}
		
		String projectName = System.getProperty(SystemEnv.PROJECT_NAME);
		ContextHolder context = ContextHolder.get();
		if (context.getSiteName() == ISite.DEFAULT_NAME) {
			context.setSiteName(projectName);
		}

		if (configuration.isJPA) {
			EntityManagerFactory emf = configuration.getEntityManagerFactory();
			EntityManager em = emf.createEntityManager();
			TransactionSynchronizationManager.bindResource(emf,
					new EntityManagerHolder(em));
		} else {
			SessionFactory sessionFactory = configuration.getSessionFactory();
			Session session = SessionFactoryUtils.getSession(sessionFactory,
					true);
			session.setFlushMode(FlushMode.MANUAL);
			TransactionSynchronizationManager.bindResource(sessionFactory,
					new SessionHolder(session));
		}
	}

	@After
	public void tearDown() throws Exception {
		if (configuration != null) {
			if (configuration.isJPA) {
				EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
						.unbindResource(configuration.getEntityManagerFactory());
				EntityManagerFactoryUtils.closeEntityManager(emHolder
						.getEntityManager());
			} else {
				SessionFactory sessionFactory = configuration.getSessionFactory();
				SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
						.unbindResource(sessionFactory);
				SessionFactoryUtils.releaseSession(sessionHolder.getSession(),
						sessionFactory);
			}
		}
	}
	
	protected void initDB(String initModel){
		List<Configuration> configs = configuration.getConfigurations();
		
		for (Configuration config : configs) {
			config.setProperty("hibernate.hbm2ddl.auto", initModel);
			config.buildSessionFactory().openStatelessSession();
		}
	}
}
